package downstream

import (
	"context"
	"google.golang.org/grpc"
	"google.golang.org/grpc/status"
	"inventory/api/bmember"
	"inventory/api/inventory"
	"inventory/internal/conf"
	"inventory/internal/constant"
	"inventory/pkg/ecode"
	"inventory/pkg/log"
	"inventory/pkg/network"
	"strconv"
	"time"
)

func newMemberClient(ctx context.Context, addr string) (
	client bmember.MemberClient, err error) {
	var conn *grpc.ClientConn
	conn, err = grpc.Dial(addr, grpc.WithInsecure(),
		grpc.WithUnaryInterceptor(network.ClientInterceptor(
			"bmember", time.Second*3, memberErrorTranslator)))
	if err != nil {
		err = ecode.AppendMessage(constant.ErrRemoteAPIFailed, "会员服务地址无法建立有效连接, err=%s", err.Error())
		log.FromContext(ctx).Warnw(err.Error())
		return
	}
	client = bmember.NewMemberClient(conn)
	return
}

func memberErrorTranslator(err error) (errCode *ecode.ErrorCode) {
	errCode = ecode.AppendMessage(
		constant.ErrRemoteAPIFailed, "会员服务调用失败：%s", status.Convert(err).Message())
	return
}

// CallMemberMatch 基于关键字查看会员id列表
func (d *Downstream) CallMemberMatch(ctx context.Context, sgID uint32, queryType inventory.QueryMemberType, keywords string) (
	memberObjs []*bmember.MemberMobileNickname, err error) {
	if d.memberClient == nil {
		if d.memberClient, err = newMemberClient(ctx, conf.Conf.Downstream.MemberURL); err != nil {
			return
		}
	}
	var nickName, mobile string
	switch queryType {
	case inventory.QueryMemberType_QUERY_MEMBER_TYPE_CONTACT:
		nickName = keywords
	case inventory.QueryMemberType_QUERY_MEMBER_TYPE_MOBILE:
		mobile = keywords
	}
	var reply *bmember.MemberMobileNicknameListReply
	if reply, err = d.memberClient.SearchMembersMobileNickname(
		ctx, &bmember.MemberMobileNicknameSearchReq{
			BrandId:  int64(sgID),
			Nickname: nickName,
			Mobile:   mobile,
		}); err != nil {
		return
	}
	memberObjs = reply.Members
	return
}

// CallMemberQuery 调用会员查询
func (d *Downstream) CallMemberQuery(ctx context.Context, memberIDs []string) (
	memberObjs []*bmember.MemberMobileNickname, err error) {
	if d.memberClient == nil {
		if d.memberClient, err = newMemberClient(ctx, conf.Conf.Downstream.MemberURL); err != nil {
			return
		}
	}
	var (
		reply     *bmember.MemberMobileNicknameListReply
		memberIds []int64
	)
	for _, memberIdStr := range memberIDs {
		var memberId int
		if memberId, err = strconv.Atoi(memberIdStr); err != nil {
			return
		}
		memberIds = append(memberIds, int64(memberId))
	}
	if reply, err = d.memberClient.GetMembersMobileNickname(
		ctx, &bmember.MemberMobileNicknameGetReq{
			MemberIds: memberIds,
		}); err != nil {
		return
	}
	memberObjs = reply.Members
	return
}

func (d *Downstream) GetMemberOpenId(ctx context.Context, memberId int64, appType string) (
	reply *bmember.MemberOpenIdGetReply, err error) {
	if d.memberClient == nil {
		if d.memberClient, err = newMemberClient(ctx, conf.Conf.Downstream.MemberURL); err != nil {
			return
		}
	}
	if reply, err = d.memberClient.GetMemberOpenIdOfBilinApp(
		ctx, &bmember.MemberOpenIdGetReq{
			MemberId: memberId,
			BilinApp: appType,
		}); err != nil {
		return
	}
	return
}
